#include <stdio.h>
#include <malloc.h>

//teste

void inicializa_matriz (Matriz** matriz, int tamanho_matriz) { //TODO corrigir ponteiragem dos irmao
	
	Matriz *novo, *atual;
 	int i;

	if (tamanho_matriz < 0)
		return; //valor invalido
	
	//cria o no super cabeca
	*matriz = (Matriz *)malloc(sizeof(Matriz));
	(*matriz)->prox_direita = *matriz;
	(*matriz)->prox_abaixo = *matriz;
	(*matriz)->lin = -1;
	(*matriz)->col = -1;

	atual = *matriz;

	for (i=0;i<tamanho_matriz;i++) {
		novo = (Matriz *)malloc(sizeof(Matriz)); //cria uma coluna
		novo->col = i;
		novo->lin = -1;
		atual->prox_direita = novo;
		novo->prox_direita = *matriz;
		novo->prox_abaixo = novo;
		atual = novo;		
	}

	atual = *matriz;

	for (i=0;i<tamanho_matriz;i++) {		
		novo = (Matriz *)malloc(sizeof(Matriz)); //cria uma linha
		novo->col = -1;
		novo->lin = i;
		atual->prox_abaixo = novo;
		novo->prox_abaixo = *matriz;
		novo->prox_direita = novo;
		atual = novo;
	}
}

void imprimir_matriz (Matriz* matriz) { //TODO comentar essa funcao

	Matriz* aux = matriz;
	int i,j;

	if (matriz == NULL) //lista vazia
		return;
	
	do {
		do {printf("%d\t%d\n",aux->lin,aux->col);
			aux = aux->prox_direita;
		} while (aux->col != -1);
		aux = aux->prox_abaixo;
	}	
		while (aux->lin != -1); 
}

void insere_no (Matriz** matriz, int tamanho_matriz, int lin, int col, char tipo, char subtipo, char cima, char baixo, char direito, char esquerdo) {
  
  Matriz* novo;	
  Matriz* aesq = *matriz;
  Matriz* acima = *matriz;

  if (*matriz == NULL){
	printf("Matriz nao existe!");  
	return;
  }

  if (tamanho_matriz <= lin || tamanho_matriz <= col){
	printf("Posicao invalida!");  
	return; 
  }

  while (lin > aesq->lin) //acha o cara logo a esquerda do novo
	aesq = aesq->prox_abaixo;

  while (col > aesq->col && aesq->prox_direita->col != -1)
    aesq = aesq->prox_direita;
  	
//  if (aesq->prox_direita->lin == lin && aesq->prox_direita->col == col){
//	printf("Elemento ja existe!");//TODO nao precisa= remover! 
//	return NULL; 
//  }

  while (col > acima->col) //acha o cara logo acima do novo  
    acima = acima->prox_direita;

  while (lin > acima->lin && acima->prox_abaixo->lin != -1) 
	acima = acima->prox_abaixo;

  novo = (Matriz *)malloc(sizeof(Matriz));
  novo->prox_direita = aesq->prox_direita;
  novo->prox_abaixo = acima->prox_abaixo;
  aesq->prox_direita = novo;
  acima->prox_abaixo = novo;
  novo->lin = lin;
  novo->col = col;
  //o ideal seria adicionar essas infos abaixo em outra funcao, ja que lin e col sempre serao adicionadas, para reaproveitar o codigo
//  novo->tipo = tipo;
//  novo->subtipo = subtipo;
//  novo->cima = cima;
//  novo->baixo = baixo;
//  novo->direito = direito;
//  novo->esquerdo = esquerdo;

  return; 
}


Matriz acha_N (Matriz* matriz, int lin, int col) { //TODO conferir se cursor ja esta na posicao encontrada dentro da main!

  Matriz* acha = *matriz;

  while (acha->col != col)
	  acha = acha->prox_direita;
  while (acha->prox_abaixo->lin < lin && acha->prox_abaixo->lin != -1)
	  acha = acha->prox_abaixo;
  
  if (acha->lin != -1){
	  return acha; 
  }
  else
	  return NULL;	
}

Matriz acha_S (Matriz* matriz, int lin, int col) {

  Matriz* acha = *matriz;

  while (acha->col != col)
	  acha = acha->prox_direita;
  while (acha->lin < lin && acha->prox_abaixo->lin != -1)
	  acha = acha->prox_abaixo;

  if (acha->lin != -1 && acha->lin > lin) {
	  return acha;
  }
  else
	  return NULL;
}

Matriz acha_O (Matriz* matriz, int lin, int col) {

  Matriz* acha = *matriz;

  while (acha->lin != lin)
	  acha = acha->prox_abaixo;
  while (acha->prox_direita->col < col && acha->prox_direita->col != -1)
	  acha = acha->prox_direita;

  if (acha->col != -1) {
	  return acha; 
  }
  else
	  return NULL;

}

Matriz acha_L (Matriz* matriz, int lin, int col) {

  Matriz* acha = *matriz;

  while (acha->lin != lin)
	  acha = acha->prox_abaixo;
  while (acha->col < col && acha->prox_direita->col != -1)
	  acha = acha->prox_direita;

  if (acha->col != -1 && acha->col > col) {
	  return acha; 
  }
  else
	  return NULL;
}
